﻿//
//  Copyright (c) 2011 Extreme: Paweł Huryn (lead), Jakub Domański
//

using System;
using System.Linq.Expressions;
using System.Text;
using Extreme.SPFramework.Configuration;

namespace Extreme.SPFramework.Presentation
{
    /// <summary>
    /// Base class for all edit presentation models
    /// </summary>
    /// <typeparam name="T">Current type</typeparam>
    [Serializable]
    public abstract class EditPresentationModelBase : PresentationModelBase, IPresentationModel
        //where T : PresentationModelBase
    {
        /// <summary>
        /// Item Identifier
        /// </summary>
        public Guid? UniqueId { get; set; }

        /// <summary>
        /// Item Identifier
        /// </summary>
        public int? Id { get; set; }

        /// <summary>
        /// Validates required field
        /// </summary>
        /// <param name="t">This</param>
        /// <param name="mapping">Mapping</param>
        /// <param name="expression">Field get expression</param>
        /// <returns></returns>
        protected string ValidateRequiredField<T>(T t, EntityMapping mapping, Expression<Func<T, object>> expression)
        {
            var propertyName = PropertyName.For(expression);
            var propertyValue = expression.Compile().Invoke(t);

            if (mapping.PropertiesMapping.ContainsKey(propertyName))
                propertyName = mapping.PropertiesMapping[propertyName].ColumnName;

            if (propertyValue == null || 
                (propertyValue is string && string.IsNullOrEmpty(propertyValue.ToString().Trim())))
                return String.Format("Pole '{0}' jest wymagane.", propertyName);
            else
                return String.Empty;
        }

        /// <summary>
        /// Validates required fields
        /// </summary>
        /// <param name="t">This</param>
        /// <param name="mapping">Mapping</param>
        /// <param name="expressions">Field get expressions</param>
        /// <returns></returns>
        protected string ValidateRequiredFields<T>(T t, EntityMapping mapping, params Expression<Func<T, object>>[] expressions)
        {
            StringBuilder localBuilder = new StringBuilder();
            foreach (var exp in expressions)
                localBuilder.AppendLine(ValidateRequiredField<T>(t, mapping, exp));
            return localBuilder.ToString();
        }

        /// <summary>
        /// Validates int range
        /// </summary>
        /// <typeparam name="T">Type of this</typeparam>
        /// <param name="t">This</param>
        /// <param name="mapping">Mapping</param>
        /// <param name="expression">Property get expression</param>
        /// <param name="from">Min value</param>
        /// <param name="to">Max value</param>
        /// <returns></returns>
        protected string ValidateIntRange<T>(T t, EntityMapping mapping, Expression<Func<T, object>> expression, int from, int to)
        {
            var propertyName = PropertyName.For(expression);
            var propertyValue = (int?)expression.Compile().Invoke(t);
            if (propertyValue == null)
                return String.Empty;

            if (mapping.PropertiesMapping.ContainsKey(propertyName))
                propertyName = mapping.PropertiesMapping[propertyName].ColumnName;

            if (propertyValue.Value < from || propertyValue.Value > to)
                return String.Format("Wartość pola '{0}' musi zawierać się w przedziale {1}-{2}.", propertyName, from, to);
            return String.Empty;
        }

        /// <summary>
        /// Validates max lenght
        /// </summary>
        /// <typeparam name="T">Type of this</typeparam>
        /// <param name="t">This</param>
        /// <param name="mapping">Mapping</param>
        /// <param name="expression">Property get expression</param>
        /// <param name="maxLength">Max length on property value</param>
        /// <returns></returns>
        protected string ValidateMaxLength<T>(T t, EntityMapping mapping, Expression<Func<T, object>> expression, int maxLength)
        {
            var propertyName = PropertyName.For(expression);
            var propertyValue = expression.Compile().Invoke(t);
            if (propertyValue == null)
                return String.Empty;

            if(propertyValue.ToString().Length > maxLength)
                return String.Format("Wartość pola '{0}' musi być ograniczona do {1} znaków.", propertyName, maxLength);
            return String.Empty;

        }
    
    }
}
